package com.csx.base.concurrency.atomic;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;

/**
 * <p> what does this class do ? </p>
 *   属性更新原子操作类的示例代码
 *   描述:
 *      该案例以Course中的 courseScore 作为原子变量
 *      存在100个线程同时对一个Course实例中的 courseScore 变量进行修改,测试属性的原子更新
 * <p> How does it work ?</p>
 * <p> Why does it do this ?</p>
 *
 * @author cuisongxu
 * @date 2024/12/3 周二 9:27
 */
public class AtomicIntegerFieldUpdaterTest {

    // 操作Course类中 courseScore 属性的原子更新类
    private static final AtomicIntegerFieldUpdater<Course> courseAIFU = AtomicIntegerFieldUpdater.newUpdater(Course.class, "courseScore");

    private final AtomicInteger courseScoreVerifier = new AtomicInteger(0);

    public void test() {

        Course course = new Course();
        Thread[] threads = new Thread[100];
        // 启动100个线程，每个线程都执行成绩累增
        for (int i = 0; i < 100; i++) {
            Thread thread = new Thread(new CourseScoreTask(course));
            threads[i] = thread;
            thread.start();
        }

        // 等待所有线程执行完毕
        for (int i = 0; i < 100; i++) {
            try {
                threads[i].join();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

        System.out.println("课程对象数值: " + course.getCourseScore());
        System.out.println("验证对象数值: " + courseScoreVerifier.get());
    }

    class CourseScoreTask implements Runnable {
        private final Course course;

        public CourseScoreTask(Course course) {
            this.course = course;
        }

        @Override
        public void run() {
            if(Math.random() > 0.4) {
                courseAIFU.incrementAndGet(course);
                courseScoreVerifier.incrementAndGet();
            }
        }
    }

    public static void main(String[] args) {
        AtomicIntegerFieldUpdaterTest atomicIntegerFieldUpdaterTest = new AtomicIntegerFieldUpdaterTest();
        atomicIntegerFieldUpdaterTest.test();
    }

    static class Course {

        private int courseId;

        private String courseName;

        // 权限方面: 不能为private修饰,如果是子类操作父类,必须为protected及以上权限
        // 可见性: 必须被volatile
        // 变量类型: 不能为static修饰的静态变量
        // 不可变: 不能被final关键字修饰
        volatile int courseScore;

        public int getCourseId() {
            return courseId;
        }

        public void setCourseId(int courseId) {
            this.courseId = courseId;
        }

        public String getCourseName() {
            return courseName;
        }

        public void setCourseName(String courseName) {
            this.courseName = courseName;
        }

        public int getCourseScore() {
            return courseScore;
        }

        public void setCourseScore(int courseScore) {
            this.courseScore = courseScore;
        }

        @Override
        public String toString() {
            return "Course{" +
                    "courseId=" + courseId +
                    ", courseName='" + courseName + '\'' +
                    ", courseScore=" + courseScore +
                    '}';
        }
    }
}
